{% extends "base.html" %}
{% block title %}
    <title>高级查询</title>
{% endblock %}


{% block content %}
    <div class="jumbotron">
        <h1>甲基化早筛项目数据库管理系统Demo</h1>
        <h4>高级查询</h4><br>
        <form id="searchForm1" role="form">
            <div class="form-group">
                <p class="bg-info text-white">
                    &nbsp;&nbsp<label class="text-white h4" for="searchModels"> 查询表</label>
                </p>
                <div>
                    <div class="h6"><span>样本管理  </span>&nbsp;&nbsp
                        <label class="checkbox-inline checkbox-lg">
                            <input type="checkbox" id="searchClinicalInfo"
                                   value="ClinicalInfo" name="searchModels" checked> 样本临床信息
                        </label>&nbsp;&nbsp
                        <label class="checkbox-inline checkbox-lg">
                            <input type="checkbox" id="searchExtractInfo"
                                   value="ExtractInfo" name="searchModels"> 样本DNA提取信息
                        </label>&nbsp;&nbsp
                        <label class="checkbox-inline checkbox-lg">
                            <input type="checkbox" id="searchDNAUsageRecordInfo"
                                   value="DNAUsageRecordInfo" name="searchModels"> 样本DNA使用记录
                        </label>&nbsp;&nbsp
                        <label class="checkbox-inline checkbox-lg">
                            <input type="checkbox" id="searchDNAInventoryInfo"
                                   value="DNAInventoryInfo" name="searchModels"> 样本DNA库存
                        </label>
                    </div>
                    <br>
                    <div class="h6"><span>文库管理  </span>&nbsp;&nbsp
                        <label class="checkbox-inline checkbox-lg">
                            <input type="checkbox" id="searchLibraryInfo"
                                   value="LibraryInfo" name="searchModels"> 样本建库信息
                        </label>&nbsp;&nbsp
                        <label class="checkbox-inline checkbox-lg">
                            <input type="checkbox" id="searchCaptureInfo"
                                   value="CaptureInfo" name="searchModels"> 捕获文库信息
                        </label>&nbsp;&nbsp
                        <label class="checkbox-inline checkbox-lg">
                            <input type="checkbox" id="searchPoolingInfo"
                                   value="PoolingInfo" name="searchModels"> Pooling映射表
                        </label>
                    </div>
                    <br>
                    <div class="h6"><span>测序管理  </span>&nbsp;&nbsp
                        <label class="checkbox-inline checkbox-lg">
                            <input type="checkbox" id="searchSequencingInfo"
                                   value="SequencingInfo" name="searchModels"> 测序上机信息
                        </label>&nbsp;&nbsp
                        <label class="checkbox-inline checkbox-lg">
                            <input type="checkbox" id="searchQCInfo"
                                   value="QCInfo" name="searchModels"> 样本测序质控信息
                        </label>
                    </div>
                </div>
            </div>
            <button type="button" class="btn btn-light h6" id="tableSet1">选取样本管理表集合</button>&nbsp;
            <button type="button" class="btn btn-light h6" id="tableSet2">选取文库管理表集合</button>&nbsp;
            <button type="button" class="btn btn-light h6" id="tableSet3">选取测序管理表集合</button>&nbsp;
            <button type="button" class="btn btn-light h6" id="tableSet4">选取所有表</button>
        </form>
        <br>

        <form id="searchForm2" role="form">
            <p class="bg-info text-white">
                &nbsp;&nbsp <label class="text-white h4" for="SearchText"> 设置过滤条件</label></p>

            <br>
            <div class="form-inline search_condition" id="condition1">
                <span class="text-info h6">过滤条件1</span>&nbsp;&nbsp;<div class="form-group">
                <label for="SearchNot1" class="bg-info text-white badge badge-primary"></label>
                <select class="form-control SearchNot" id="SearchNot1" name="SearchNot1" required="true">
                    <option value="0" selected="selected"></option>
                    <option value="1">非</option>
                </select>
            </div>&nbsp;&nbsp
                <div class="form-group">
                    <label for="SearchModelName1" class="bg-info text-white h6">查询子表
                    </label>&nbsp;&nbsp
                    <select class="form-control SearchModelName" id="SearchModelName1" name="SearchModelName1"
                            required="true">
                    </select>
                </div>&nbsp;&nbsp
                <div class="form-group">
                    <label for="SearchFieldName1" class="bg-info text-white h6">查询字段
                    </label>&nbsp;&nbsp
                    <select class="form-control SearchFieldName" id="SearchFieldName1" name="SearchFieldName1"
                            required="true">
                    </select>
                </div>&nbsp;&nbsp
                <div class="form-group">
                    <label for="SearchFieldValue1" class="bg-info text-white h6">查询字段值
                    </label>&nbsp
                    <select class="form-control SearchFieldValuePre" id="SearchFieldValuePre1"
                            name="SearchFieldValuePre1" required="true">
                        <option value="exact" selected="selected">等于(大小写严格匹配)</option>
                        <option value="iexact">等于(忽略大小写)</option>
                        <option value="contains">包含(大小写严格匹配)</option>
                        <option value="icontains">包含(忽略大小写)</option>
                        <option value="gt">大于</option>
                        <option value="gte">大于等于</option>
                        <option value="lt">小于</option>
                        <option value="lte">小于等于</option>
                    </select>&nbsp
                    <input type="text" class="form-control SearchFieldValue" id="SearchFieldValue1"
                           name="SearchFieldValue1" placeholder="请输入查询字段值">
                </div>
            </div>
        </form>
        <br>
        <div class="form-inline mb-1">
            <button id='textareaAdd' class="btn btn-primary h6">确认过滤条件</button>&nbsp;&nbsp
            <button id='conditionAdd' class="btn btn-info h6">添加过滤条件</button>
        </div>
        <br>
        <form id="searchForm3" role="form">
            {% csrf_token %}
            <div class="form-group">
                <p class="bg-info text-white">
                    &nbsp;&nbsp <label class="text-white h4" for="SearchText"> 过滤条件如下:</label></p>
                <textarea class="form-control" rows="3" id="SearchText" name="SearchText"></textarea>
            </div>
            <button id='textareaSubmit' type="submit"
                    class="btn btn-primary">查询
            </button>
            <button id='textareaClear' type="button" class="btn btn-danger">清除</button>
        </form>
    </div>
{% endblock %}



{% block plot %}
    <!-- highcharts -->
    <div id="resetPlot">
    </div>
{% endblock %}


{% block table %}
    <!-- datatables -->
    <div id="resetTable">
    </div>

{% endblock %}


{% block extra_js %}
    <script>
        $(document).ready(function () {
            for (let i = 2; i <= 10; i++) {
                let str = '<div class="form-inline search_condition" id="condition' + i + '">';
                str += '<span class="text-info h6">过滤条件' + i + '</span>&nbsp;&nbsp;<div class="form-group">' +
                    '<label for="SearchNot' + i + '" class="bg-primary text-white badge badge-info"></label>' +
                    '<select class="form-control SearchNot" id="SearchNot' + i + '" name="SearchNot' + i
                    + '"><option value="0" selected="selected"></option><option value="1">非' +
                    '</option></select></div>&nbsp;&nbsp;';
                str += '<div class="form-group"><label for="SearchModelName' + i + '" class="bg-info text-white ' +
                    'h6">查询子表</label>&nbsp;&nbsp<select class="form-control ' +
                    'SearchModelName" id="SearchModelName' + i + '" name="SearchModelName' + i + '"></select>' +
                    '</div>&nbsp;&nbsp;';
                str += '<div class="form-group"><label for="SearchFieldName' + i + '" class="bg-info text-white ' +
                    'h6">查询字段</label>&nbsp;&nbsp<select class="form-control ' +
                    'SearchFieldName" id="SearchFieldName' + i + '" name="SearchFieldName' + i + '"></select>' +
                    '</div>&nbsp;&nbsp;';
                str += '<div class="form-group"><label for="SearchFieldValue' + i + '" class="bg-info text-white ' +
                    'h6">查询字段值</label>&nbsp<select class="form-control ' +
                    'SearchFieldValuePre" id="SearchFieldValuePre' + i + '" name="SearchFieldValuePre' + i +
                    '" required="true"><option value="exact" selected="selected">等于(大小写严格匹配)</option>' +
                    '<option value="iexact">等于(忽略大小写)</option><option value="contains">包含(大小写严格匹配)' +
                    '</option><option value="icontains">包含(忽略大小写)</option><option value="gt">大于</option>' +
                    '<option value="gte">大于等于</option><option value="lt">小于</option><option value="lte">小于等于' +
                    '</option></select>&nbsp;';
                str += '<input type="text" class="form-control SearchFieldValue" id="SearchFieldValue' + i + '" ' +
                    'name="SearchFieldValue' + i + '" placeholder="请输入查询字段值"></div></div>';
                $('#searchForm2').append(str);
                $('#condition' + i).hide();
            }
            // 选取样本管理表集合 按钮功能
            let click1 = 0;
            $('#tableSet1').click(function (e) {
                    e.preventDefault();
                if (click1 === 0) {
                    click1 = 1;
                } else {
                    click1 = 0;
                }
                    $(this).button('toggle');
                    $(this).blur();
                    $.each(['ExtractInfo', 'DNAUsageRecordInfo', 'DNAInventoryInfo'], function (index_, value_) {
                        let str_ = '#search' + value_;
                        if (click1 === 0) {
                            $(str_).prop("checked", false);
                        } else {
                            $(str_).prop("checked", true);
                        }
                    });
                }
            );
            // 选取文库管理表集合 按钮功能
            let click2 = 0;
            $('#tableSet2').click(function (e) {
                    e.preventDefault();
                if (click2 === 0) {
                    click2 = 1;
                } else {
                    click2 = 0;
                }
                    $(this).button('toggle');
                    $(this).blur();
                    $.each(['LibraryInfo', 'CaptureInfo', 'PoolingInfo'], function (index_, value_) {
                        let str_ = '#search' + value_;
                        if (click2 === 0) {
                            $(str_).prop("checked", false);
                        } else {
                            $(str_).prop("checked", true);
                        }
                    });
                }
            );
            // 选取测序管理表集合 按钮功能
            let click3 = 0;
            $('#tableSet3').click(function (e) {
                    e.preventDefault();
                if (click3 === 0) {
                    click3 = 1;
                } else {
                    click3 = 0;
                }
                    $(this).button('toggle');
                    $(this).blur();
                    $.each(['SequencingInfo', 'QCInfo'], function (index_, value_) {
                        let str_ = '#search' + value_;
                        if (click3 === 0) {
                            $(str_).prop("checked", false);
                        } else {
                            $(str_).prop("checked", true);
                        }
                    });
                }
            );
            // 选取所有表集合 按钮功能
            let click4 = 0;
            $('#tableSet4').click(function (e) {
                    e.preventDefault();
                if (click4 === 0) {
                    click4 = 1;
                } else {
                    click4 = 0;
                }
                    $(this).button('toggle');
                    $(this).blur();
                    $.each(['ExtractInfo', 'DNAUsageRecordInfo', 'DNAInventoryInfo', 'LibraryInfo',
                        'CaptureInfo', 'PoolingInfo', 'SequencingInfo', 'QCInfo'
                    ], function (index_, value_) {
                        let str_ = '#search' + value_;
                        if (click4 === 0) {
                            $(str_).prop("checked", false);
                        } else {
                            $(str_).prop("checked", true);
                        }
                    });
                }
            );
            // 查询子表下拉选框
            let models2label = {
                ClinicalInfo: '样本临床信息',
                ExtractInfo: '样本DNA提取信息',
                DNAUsageRecordInfo: '样本DNA使用记录',
                DNAInventoryInfo: '样本DNA库存',
                LibraryInfo: '样本建库信息',
                CaptureInfo: '捕获文库信息',
                PoolingInfo: 'Pooling映射表',
                SequencingInfo: '测序上机信息',
                QCInfo: '样本测序质控信息'
            };
            $('.search_condition .SearchModelName').focus(function () {
                // 获取想要查询的表
                $(this).empty();
                $(this).parents('.search_condition').find('.SearchFieldName').empty();
                $(this).parents('.search_condition').find('.SearchFieldValuePre').val('exact');
                $(this).parents('.search_condition').find('.SearchFieldValue').empty();
                let str = "";
                $("input[name='searchModels']:checked").each(function (i) {
                    let key_ = $(this).val();
                    str += '<option value="' + key_ +
                        '">' + models2label[key_] + '</option>';
                });
                $(this).append(str);

            });
            // 表格显示表头列名称
            let modelLabel = {
                'normal': {
                    'ClinicalInfo': ['姓名', '性别', '年龄', '住院号', '癌种', '分期', '诊断', '诊断备注',
                        '采样日期', '医院编号', '科室', '血浆管数', '癌旁组织样本数量', '癌组织样本数量',
                        '白细胞样本数量', '粪便样本数量', '寄送日期', '临床信息-备注'],
                    'ExtractInfo': ['提取日期', '样本类型', '样本体积(ml)', '提取方法', '浓度(ng/ul)', '体积(ul)',
                        '提取信息-备注'],
                    'DNAUsageRecordInfo': ['使用日期', '使用量', '用途', '建库编号(如有)', '使用记录-备注'],
                    'DNAInventoryInfo': ['DNA提取总量(ng)', '成功建库使用量(ng)', '失败建库使用量(ng)',
                        '科研项目使用量(ng)', '其他使用量(ng)', '剩余量(ng)'],
                    'LibraryInfo': ['管上编号', '是否临床', '文库名', '样本标签', 'index列表', '建库日期', '建库方法',
                        '试剂批次', '建库-起始量', '建库-PCR循环数', '建库-文库浓度', '建库-文库体积', '建库-操作人',
                        '建库信息-备注'],
                    'CaptureInfo': ['杂交日期', '杂交探针', '捕获文库-杂交时间(min)', '捕获文库-PostPCR循环数',
                        '捕获文库-PostPCR浓度(ng/ul)', '捕获文库-洗脱体积(ul)', '捕获文库-操作人', '捕获文库-备注'],
                    'PoolingInfo': ['pooling比例', 'pooling取样(ng)', 'pooling体积(ul)', 'pooling信息-备注'],
                    'SequencingInfo': ['送测日期', '上机时间', '下机时间', '测序-机器号', '测序-芯片号', '测序-备注'],
                    'QCInfo': ['QC编号', 'Data_Size(Gb)', 'Clean_Rate(%)', 'R1_Q20', 'R2_Q20', 'R1_Q30',
                        'R2_Q30', 'GC_Content', 'BS_conversion_rate(lambda_DNA)', 'BS_conversion_rate(CHH)',
                        'BS_conversion_rate(CHG)', 'Uniquely_Paired_Mapping_Rate', 'Mismatch_and_InDel_Rate',
                        'Mode_Fragment_Length(bp)', 'Genome_Duplication_Rate', 'Genome_Depth(X)',
                        'Genome_Dedupped_Depth(X)', 'Genome_Coverage', 'Genome_4X_CpG_Depth(X)',
                        'Genome_4X_CpG_Coverage', 'Genome_4X_CpG_methylation_level', 'Panel_4X_CpG_Depth(X)',
                        'Panel_4X_CpG_Coverage', 'Panel_4X_CpG_methylation_level', 'Panel_Ontarget_Rate(region)',
                        'Panel_Duplication_Rate(region)', 'Panel_Depth(site,X)', 'Panel_Dedupped_Depth(site,X)',
                        'Panel_Coverage(site,1X)', 'Panel_Coverage(site,10X)', 'Panel_Coverage(site,20X)',
                        'Panel_Coverage(site,50X)', 'Panel_Coverage(site,100X)', 'Panel_Uniformity(site,>20%mean)',
                        'Strand_balance(F)', 'Strand_balance(R)', 'GC_bin_depth_ratio', '质控-备注']
                },
                'link': {
                    'ClinicalInfo': ['样本编号'],
                    'ExtractInfo': ['样本编号', 'DNA提取编号'],
                    'DNAUsageRecordInfo': ['样本编号', 'DNA提取编号'],
                    'DNAInventoryInfo': ['样本编号', 'DNA提取编号'],
                    'LibraryInfo': ['样本编号', 'DNA提取编号', '建库编号'],
                    'CaptureInfo': ['捕获文库名'],
                    'PoolingInfo': ['样本编号', 'DNA提取编号', '建库编号', '捕获文库名', '测序文库名'],
                    'SequencingInfo': ['捕获文库名', '上机文库号'],
                    'QCInfo': ['样本编号', 'DNA提取编号', '建库编号', '捕获文库名', '测序文库名', '上机文库号']
                }
            };
            // 字典，用于构建request查询数据库，值与model的field一致
            let modelCol = {
                'normal': {
                    'ClinicalInfo': ['name', 'gender', 'age', 'patientId', 'category', 'stage', 'diagnose',
                        'diagnose_others', 'centrifugation_date', 'hospital', 'department', 'plasma_num',
                        'adjacent_mucosa_num', 'cancer_tissue_num', 'WBC_num', 'stool_num', 'send_date', 'others'],
                    'ExtractInfo': ['extract_date', 'sample_type', 'sample_volume', 'extract_method',
                        'dna_con', 'dna_vol', 'others'],
                    'DNAUsageRecordInfo': ['LB_date', 'mass', 'usage', 'singleLB_id', 'others'],
                    'DNAInventoryInfo': ['totalM', 'successM', 'failM', 'researchM', 'othersM', 'remainM'],
                    'LibraryInfo': ['tube_id', 'clinical_boolen', 'singleLB_name', 'label', 'barcodes', 'LB_date',
                        'LB_method', 'kit_batch', 'mass', 'pcr_cycles', 'LB_con', 'LB_vol', 'operator',
                        'others'],
                    'CaptureInfo': ['hybrid_date', 'probes', 'hybrid_min', 'postpcr_cycles', 'postpcr_con',
                        'elution_vol', 'operator', 'others'],
                    'PoolingInfo': ['pooling_ratio', 'mass', 'volume', 'others'],
                    'SequencingInfo': ['send_date', 'start_time', 'end_time', 'machine_id', 'chip_id', 'others'],
                    'QCInfo': ['QC_id', 'data_size_gb_field', 'clean_rate_field', 'r1_q20', 'r2_q20', 'r1_q30',
                        'r2_q30', 'gc_content', 'bs_conversion_rate_lambda_dna_field', 'bs_conversion_rate_chh_field',
                        'bs_conversion_rate_chg_field', 'uniquely_paired_mapping_rate', 'mismatch_and_indel_rate',
                        'mode_fragment_length_bp_field', 'genome_duplication_rate', 'genome_depth_x_field',
                        'genome_dedupped_depth_x_field', 'genome_coverage', 'genome_4x_cpg_depth_x_field',
                        'genome_4x_cpg_coverage', 'genome_4x_cpg_methylation_level', 'panel_4x_cpg_depth_x_field',
                        'panel_4x_cpg_coverage', 'panel_4x_cpg_methylation_level', 'panel_ontarget_rate_region_field',
                        'panel_duplication_rate_region_field', 'panel_depth_site_x_field',
                        'panel_dedupped_depth_site_x_field', 'panel_coverage_site_1x_field',
                        'panel_coverage_site_10x_field', 'panel_coverage_site_20x_field',
                        'panel_coverage_site_50x_field', 'panel_coverage_site_100x_field',
                        'panel_uniformity_site_20_mean_field', 'strand_balance_f_field', 'strand_balance_r_field',
                        'gc_bin_depth_ratio', 'others']
                },
                'link': {
                    'ClinicalInfo': ['sample_id'],
                    'ExtractInfo': ['sample_id', 'dna_id'],
                    'DNAUsageRecordInfo': ['sample_id', 'dna_id'],
                    'DNAInventoryInfo': ['sample_id', 'dna_id'],
                    'LibraryInfo': ['sample_id', 'dna_id', 'singleLB_id'],
                    'CaptureInfo': ['poolingLB_id'],
                    'PoolingInfo': ['sample_id', 'dna_id', 'singleLB_id', 'poolingLB_id', 'singleLB_Pooling_id'],
                    'SequencingInfo': ['poolingLB_id', 'sequencing_id'],
                    'QCInfo': ['sample_id', 'dna_id', 'singleLB_id', 'poolingLB_id', 'singleLB_Pooling_id', 'sequencing_id']
                }
            };
            // 查询字段名下拉选框
            $('.search_condition .SearchFieldName').focus(function () {
                // 获取想要查询的字段名
                $(this).empty();
                $(this).parents('.search_condition').find('.SearchFieldValuePre').val('exact');
                $(this).parents('.search_condition').find('.SearchFieldValue').empty();
                let key_ = $(this).parents('.search_condition').find('.SearchModelName').val();
                //alert(key_);
                let str = '';
                $.each(modelLabel['link'][key_], function (i, v) {
                    str += '<option value="' + modelCol['link'][key_][i] +
                        '">' + v + '</option>';
                });
                $.each(modelLabel['normal'][key_], function (i, v) {
                    str += '<option value="' + modelCol['normal'][key_][i] +
                        '">' + v + '</option>';
                });
                $(this).append(str);
            });
            // 查询字段值下拉选框
            $('.search_condition .SearchFieldValue').focus(function () {
                // 获取想要查询的字段值
                $(this).empty();
                let key1 = $(this).parents('.search_condition').find('.SearchModelName').val();
                let key2 = $(this).parents('.search_condition').find('.SearchFieldName').val();
                let values = $.ajax({
                    url: "{% url 'unique' %}", data: {model: key1, filed: key2},
                    dataType: 'json', contentType: "application/json",
                    method: "GET", async: false
                }).responseJSON.values;
                //console.info("key1:", key1, "key2:", key2, "values:", values, "values.length:",values.length);
                //console.info("this.id", '#'+$(this).attr('id'));
                input_autocomplete(values, '#' + $(this).attr('id'));
            });

            // 实现"添加过滤条件"按钮的功能
            let conditionAdd = 1;
            $('#conditionAdd').click(function (e) {
                e.preventDefault();
                conditionAdd += 1;
                $('#condition' + conditionAdd).show();
                if (conditionAdd === 10) {
                    $('#conditionAdd').attr("disabled", true);
                }
            });

            // 实现"添加到文本框"按钮的功能
            $('#textareaAdd').click(function (e) {
                e.preventDefault();
                let text = ''; // 储存值
                for (let i = 1; i <= 10; i++) {
                    let not = $('#SearchNot' + i).val(); //获取查询字段
                    let model = $('#SearchModelName' + i).val(); //获取查询字段
                    let name = $('#SearchFieldName' + i).val(); //获取查询字段
                    let valuePre = $('#SearchFieldValuePre' + i).val(); //获取查询字段值
                    let value = $('#SearchFieldValue' + i).val(); //获取查询字段值
                    if (!model && !name && !value) {
                        // do nothing
                    } else {
                        if (!text) {
                            text = '(' + not + "\t" + model + "\t" + name + "\t" + valuePre + "\t" + value + ')';
                        } else {
                            text += ' AND (' + not + "\t" + model + "\t" + name + "\t" + valuePre + "\t" +
                                value + ')';
                        }
                    }
                }
                $("#SearchText").val(text);  //最后再直接输入到文本框，覆盖原本的值
                // 复位过滤条件
                $('.search_condition .SearchNot').val("");
                $('.search_condition .SearchModelName').empty();
                $('.search_condition .SearchFieldName').empty();
                $('.search_condition .SearchFieldValuePre').val('exact');
                $('.search_condition .SearchFieldValue').val("");
                // 复位"添加过滤条件"按钮
                for (; conditionAdd > 1; conditionAdd--) {
                    $('#condition' + conditionAdd).hide();
                }
                $('#conditionAdd').attr("disabled", false);
            });

            // 实现"清除"按钮的功能
            $('#textareaClear').click(function (e) {
                e.preventDefault();
                $("#SearchText").val("");
            });

            // 实现"查询"按钮的功能
            $('#textareaSubmit').click(function (e) {
                e.preventDefault();
                $("#resetTable").empty(); //再次click后，先将datatable删除
                $("#resetPlot").empty(); //再次click后，先将plot删除
                // 获取想要查询的表
                let models = [];
                $("input[name='searchModels']:checked").each(function (i) {
                    models[i] = $(this).val();
                });
                // 根据查询模型生成table列标题，前面列固定为连接字段数组(['样本编号', 'DNA提取编号', '建库编号',
                // 'pooling号', '文库编号', '测序编号'])中的元素，后面为各表自定义字段
                let tableLinkCol = []; // 记录有效的连接字段数组元素
                let tableNormalCol = []; // 记录各表自定义字段名称
                let returnCols = []; // 构建request返回数据对应的col数组
                returnCols.push({
                    data: 'index',
                    width: "1%",
                    // 若想前端显示的不一样，则需要"render"函数
                    'render': function (data, type, full, meta) {
                        return meta.row + 1 + meta.settings._iDisplayStart;
                    }
                });
                let htmlStr = ""; // 储存生成的html代码
                let tableNormalField = []; // 记录表头字段原来的field
                htmlStr = '<table id="table_id" class="display"><thead><tr id="tableColName"><th>索引</th>';
                let forList = ['ClinicalInfo', 'ExtractInfo', 'DNAUsageRecordInfo', 'DNAInventoryInfo',
                    'LibraryInfo', 'CaptureInfo', 'PoolingInfo', 'SequencingInfo', 'QCInfo'];
                $.each(forList, function (i, v) {
                    if (models.indexOf(v) > -1) {
                        $.each(modelLabel['normal'][v], function (i2, v2) {
                            tableNormalCol.push(v2);
                            tableNormalField.push(v + "_" + modelCol['normal'][v][i2]);
                        });
                        $.each(modelLabel['link'][v], function (i2, v2) {
                            if (tableLinkCol.indexOf(v2) === -1) {
                                tableLinkCol.push(v2);
                            }

                        });
                    }
                });
                let link_n = 0;
                $.each(['样本编号', 'DNA提取编号', '建库编号', '捕获文库名', '测序文库名', '上机文库号'], function (index_, value_) {
                    if (tableLinkCol.indexOf(value_) !== -1) {
                        htmlStr += '<th>' + value_ + '</th>';
                        returnCols.push({"data": "link" + link_n});
                        link_n++;
                    }
                });
                $.each(tableNormalCol, function (i, v) {
                    htmlStr += '<th>' + v + '</th>';
                    returnCols.push({"data": "normal" + i});
                });
                htmlStr += '</tr></thead></table>';
                $("#resetTable").append(htmlStr); //插入html代码
                // 使用ajax跟后端进行交互，获取数据后生成datatables
                let ajax_output = {};
                let table = $('#table_id').DataTable({
                    "language": {
                        "lengthMenu": "选择每页 _MENU_ 展示 ",
                        "zeroRecords": "未找到匹配结果--抱歉",
                        "info": "当前显示第 _PAGE_ 页结果，共 _PAGES_ 页",
                        "infoEmpty": "没有数据",
                        "search": "搜索",
                        "infoFiltered": "(获取 _MAX_ 项结果)",
                        "paginate": {
                            "first": "首页",
                            "previous": "上一页",
                            "next": "下一页",
                            "last": "末页"
                        }
                    },
                    "scrollY": "5000px",
                    "scrollCollapse": true,
                    "scrollX": true,
                    "pagingType": "full_numbers",
                    fixedColumns: true,
                    rowReorder: true,
                    colReorder: true,
                    searching: true,
                    select: true,
                    dom: 'lB<"clear">frtip',
                    buttons: [
                        {
                            text: '显示列', extend: 'colvis',
                            postfixButtons: ['colvisRestore'],
                            columnText: function (dt, idx, title) {
                                return (idx + 1) + ': ' + title;
                            }
                        },
                        {
                            extend: 'selectAll',
                            text: '全选'
                        }, {
                            extend: 'selectRows',
                            text: '选择多行'
                        }, {
                            extend: 'selectNone',
                            text: '取消当前选择'
                        },
                        {
                            extend: 'copy',
                            text: '复制到剪切板'
                        }, {
                            extend: 'csv',
                            text: '输出到csv'
                        }
                    ],
                    "lengthMenu": [[10, 25, 50, 100, -1], [10, 25, 50, 100, "全部"]],
                    //"serverSide": true,
                    "processing": true,
                    "ajax": {
                        "url": "{% url 'AdvancedSearch' %}",
                        "type": "POST",
                        "data": function (d) {
                            return $.extend({}, d, {
                                "modellist": models.join(', '),
                                "queryset": $("#SearchText").val()
                            });
                        },
                        "dataSrc": function (json) {
                            ajax_output = json.data;
                            // console.log(ajax_output);//此处json就是返回的数据
                            return json.data;
                        }
                    },
                    "deferRender": true,
                    "columns": returnCols
                });

                // 根据datatables画图
                function plot_bubble_by_group(tmp_data, tmp_models, tmp_fields, x_num, y_num,
                                              tmp_xAxis, tmp_yAxis, tmp_plotOptions, tmp_tooltip,
                                              tmp_title) {
                    let series_array = [];
                    let idx2categories = {
                        'x': {},
                        'y': {}
                    };
                    if (x_num !== 1) {
                        tmp_xAxis['categories'] = tmp_data[0]['categories'];
                        tmp_xAxis['min'] = 0;
                        tmp_xAxis['max'] = tmp_data[0]['categories'].length - 1;
                        $.each(tmp_data[0]['categories'], function (i, v) {
                            idx2categories['x'][i] = v;
                        });
                    }
                    if (y_num !== 1) {
                        tmp_yAxis['categories'] = tmp_data[1]['categories'];
                        tmp_yAxis['min'] = 0;
                        tmp_yAxis['max'] = tmp_data[1]['categories'].length - 1;
                        $.each(tmp_data[1]['categories'], function (i, v) {
                            idx2categories['y'][i] = v;
                        });
                    }
                    if (tmp_data[2]['item_type'] === 'str') { // 有分组
                        if (x_num !== 1 && y_num !== 1) {
                            tmp_tooltip = {
                                formatter: function () {
                                    return ' group: ' + this.series.name + ' x: ' + idx2categories['x'][parseInt(this.x)] +
                                        ' y: ' + idx2categories['y'][parseInt(this.y)] + ' size: ' + this.point.z;
                                }
                            };
                        } else if (x_num !== 1 && y_num === 1) {
                            tmp_tooltip = {
                                formatter: function () {
                                    return ' group: ' + this.series.name + ' x: ' + idx2categories['x'][parseInt(this.x)] +
                                        ' y: ' + this.y + ' size: ' + this.point.z;
                                }
                            };
                        } else {
                            tmp_tooltip = {
                                formatter: function () {
                                    return ' group: ' + this.series.name + ' x: ' + this.x +
                                        ' y: ' + idx2categories['y'][parseInt(this.y)] + ' size: ' + this.point.z;
                                }
                            };
                        }
                        tmp_title.text += ' (group by ' + tmp_models[2].val() + ' - ' + tmp_fields[2].val() + ') ';
                        tmp_plotOptions = {
                            bubble: {
                                showInLegend: true
                            }
                        };
                        let tmp_group_dict = {};
                        let name_series = [];
                        let data_series = [];
                        $.each(tmp_data[2]['categories'], function (i, v) {
                            name_series.push(v);
                            data_series.push([]);
                            tmp_group_dict[i] = {};
                        });
                        $.each(tmp_data[2]['data'], function (i, v) {
                            let tmp_k = tmp_data[0]['data'][i] + '_' + tmp_data[1]['data'][i];
                            if (tmp_group_dict[v] === undefined) {
                                tmp_group_dict[v] = {tmp_k: 1};
                            } else if (tmp_group_dict[v][tmp_k] === undefined) {
                                tmp_group_dict[v][tmp_k] = 1;
                            } else {
                                tmp_group_dict[v][tmp_k] += 1;
                            }
                        });
                        $.each(tmp_data[2]['categories'], function (i,) {
                            $.each(tmp_group_dict[i], function (k, v2) {
                                let v_list = k.split("_");
                                data_series[i].push([parseFloat(v_list[0]), parseInt(v_list[1]), v2]);
                            });
                        });
                        $.each(data_series, function (i, v) {
                            series_array.push({
                                name: name_series[i],
                                data: v
                            });
                        });
                    } else { // 无分组
                        tmp_plotOptions = {
                            bubble: {
                                showInLegend: false
                            }
                        };
                        if (x_num !== 1 && y_num !== 1) {
                            tmp_tooltip = {
                                formatter: function () {
                                    return ' x: ' + idx2categories['x'][parseInt(this.x)] +
                                        ' y: ' + idx2categories['y'][parseInt(this.y)] + ' size: ' + this.point.z;
                                }
                            };
                        } else if (x_num !== 1 && y_num === 1) {
                            tmp_tooltip = {
                                formatter: function () {
                                    return ' x: ' + idx2categories['x'][parseInt(this.x)] +
                                        ' y: ' + this.y + ' size: ' + this.point.z;
                                }
                            };
                        } else {
                            tmp_tooltip = {
                                formatter: function () {
                                    return ' x: ' + this.x +
                                        ' y: ' + idx2categories['y'][parseInt(this.y)] + ' size: ' + this.point.z;
                                }
                            };
                        }
                        let tmp_group_dict = {};
                        $.each(tmp_data[0]['data'], function (i,) {
                            let tmp_k = tmp_data[0]['data'][i] + '_' + tmp_data[1]['data'][i];
                            if (tmp_group_dict[tmp_k] === undefined) {
                                tmp_group_dict[tmp_k] = 1;
                            } else {
                                tmp_group_dict[tmp_k] += 1;
                            }
                        });
                        let data_series = [];
                        $.each(tmp_group_dict, function (k, v) {
                            let v_list = k.split("_");
                            data_series.push([parseFloat(v_list[0]), parseInt(v_list[1]), v]);
                        });
                        series_array.push({
                            name: 'None',
                            data: data_series
                        });
                    }
                    return series_array;
                }

                htmlStr = '<div class="row">' +
                    '<div id="plot_highcharts" style="width: 550px; height: 600px; margin: 0 auto" class="col-9"></div>' +
                    '<div id="plot_button" class="form-group col-3">' +
                    '<label for="plot_highcharts_class"> 请选择画图类型</label>' +
                    '<select class="form-control" id="plot_highcharts_class">' +
                    '<option value="None" selected="selected">---</option>' +
                    '<option value="pie">饼图</option>' +
                    '<option value="scatter">散点图</option>' +
                    '</select><br><button type="button" class="btn btn-success" id="plotShow">确认</button>' +
                    '' +
                    '<p id="plotShowError"></p></div></div><br>';
                $("#resetPlot").append(htmlStr); //插入html代码
                let plot_dict = {
                    'ClinicalInfo': [1, 2, 4, 6, 8, 9, 16],
                    'ExtractInfo': [0, 1, 2, 3, 4, 5],
                    'DNAUsageRecordInfo': [0, 1, 2],
                    'DNAInventoryInfo': [0, 1, 2, 3, 4],
                    'LibraryInfo': [1, 3, 5, 6, 7, 8, 9, 10, 11, 12],
                    'CaptureInfo': [0, 1, 2, 3, 4, 5, 6],
                    'PoolingInfo': [0, 1, 2],
                    'SequencingInfo': [0, 1, 2, 3, 4],
                    'QCInfo': [
                        1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
                        11, 12, 13, 14, 15, 16, 17, 18, 19, 20,
                        21, 22, 23, 24, 25, 26, 27, 28, 29, 30,
                        31, 32, 33, 34, 35, 36]
                };
                let plotClass = $('#plot_highcharts_class');
                plotClass.change(function () {
                    $("#plot_highcharts_input").empty(); //先将plot_highcharts_input删除
                    htmlStr = '<div id="plot_highcharts_input"></div>';
                    plotClass.after(htmlStr);
                    let plot_highcharts_input = $("#plot_highcharts_input");
                    plot_highcharts_input.on('change', '.plot_highcharts_model', function () {
                        // 处理逻辑
                        $(this).next().remove(); // 删除字段label
                        $(this).next().remove(); // 删除字段select
                        if ($(this).val() === 'None') {
                            // do nothing
                        } else {
                            htmlStr = '<label> 字段</label><select class="form-control plot_highcharts_field">' +
                                '<option value="None" selected="selected">---</option>';
                            let this_value = $(this).val();
                            $.each(plot_dict[this_value], function (i, v) {
                                htmlStr += '<option value="' + modelCol['normal'][this_value][v] + '">' +
                                    modelLabel['normal'][this_value][v] + '</option>';
                            });
                            htmlStr += '</select>';
                            $(this).after(htmlStr);
                        }
                    });
                    if (plotClass.val() === 'pie') {
                        htmlStr = '<label for="plot_highcharts_model"> 请选择用于画图的子表</label>' +
                            '<select class="form-control plot_highcharts_model" id="plot_highcharts_model">' +
                            '<option value="None" selected="selected">---</option>';
                        $.each(forList, function (i, v) {
                            if (models.indexOf(v) > -1) {
                                htmlStr += '<option value="' + v + '">' + models2label[v] + '</option>';
                            }
                        });
                        htmlStr += '</select><label> 字段</label><select class="form-control plot_highcharts_field">' +
                            '<option value="None" selected="selected">---</option></select>';
                    } else if (plotClass.val() === 'scatter') {
                        htmlStr = '<label for="plot_highcharts_model1"> 请选择用于x轴的数据: 子表</label>' +
                            '<select class="form-control plot_highcharts_model" id="plot_highcharts_model1">' +
                            '<option value="None" selected="selected">---</option>';
                        $.each(forList, function (i, v) {
                            if (models.indexOf(v) > -1) {
                                htmlStr += '<option value="' + v + '">' + models2label[v] + '</option>';
                            }
                        });
                        htmlStr += '</select><label> 字段</label><select class="form-control plot_highcharts_field">' +
                            '<option value="None" selected="selected">---</option></select>';
                        htmlStr += '<label for="plot_highcharts_model2"> 请选择用于y轴的数据: 子表</label>' +
                            '<select class="form-control plot_highcharts_model" id="plot_highcharts_model2">' +
                            '<option value="None" selected="selected">---</option>';
                        $.each(forList, function (i, v) {
                            if (models.indexOf(v) > -1) {
                                htmlStr += '<option value="' + v + '">' + models2label[v] + '</option>';
                            }
                        });
                        htmlStr += '</select><label> 字段</label><select class="form-control plot_highcharts_field">' +
                            '<option value="None" selected="selected">---</option></select>';
                        htmlStr += '<label for="plot_highcharts_model3"> 请选择用于分组的数据: 子表</label>' +
                            '<select class="form-control plot_highcharts_model" id="plot_highcharts_model3">' +
                            '<option value="None" selected="selected">---</option>';
                        $.each(forList, function (i, v) {
                            if (models.indexOf(v) > -1) {
                                htmlStr += '<option value="' + v + '">' + models2label[v] + '</option>';
                            }
                        });
                        htmlStr += '</select><label> 字段</label><select class="form-control plot_highcharts_field">' +
                            '<option value="None" selected="selected">---</option></select>';
                        htmlStr += '<label class="checkbox-inline">';
                        htmlStr += '<input type="checkbox" id="scatter_remove_abnormal">剔除异常极值(当x或y轴为数值型变量时可用)</lable>';
                    }

                    plot_highcharts_input.append(htmlStr);
                });

                // 画图确认 按钮功能
                $('#plotShow').click(function (e) {
                    e.preventDefault();
                    let field_type = {
                        'str': [
                            "ClinicalInfo_gender", "ClinicalInfo_category", "ClinicalInfo_diagnose", "ClinicalInfo_hospital",
                            "ExtractInfo_sample_type", "ExtractInfo_extract_method",
                            "DNAUsageRecordInfo_usage",
                            "LibraryInfo_clinical_boolen", "LibraryInfo_label", "LibraryInfo_LB_method", "LibraryInfo_kit_batch", "LibraryInfo_operator",
                            "CaptureInfo_probes", "CaptureInfo_operator",
                            "SequencingInfo_machine_id", "SequencingInfo_chip_id"
                        ],
                        'date': [
                            "ClinicalInfo_centrifugation_date", "ClinicalInfo_send_date",
                            "ExtractInfo_extract_date",
                            "DNAUsageRecordInfo_LB_date",
                            "LibraryInfo_LB_date",
                            "CaptureInfo_hybrid_date",
                            "SequencingInfo_send_date", "SequencingInfo_start_time", "SequencingInfo_end_time"
                        ]
                    };
                    $("#plotShowError").text("");
                    if (plotClass.val() === 'pie') {
                        let this_model = $('#plot_highcharts_model');
                        let this_field = this_model.next().next();
                        if (this_model.val === 'None' || this_field.val === 'None') {
                            $("#plotShowError").text("请正确选择x和y轴数据源(包括子表和字段)");
                            return;
                        }
                        let tmp_data = {
                            'sum': 0,
                            'data': {}
                        };
                        let tmp_k = this_model.val() + '_' +
                            this_field.val();
                        let tmp_data_key = [];
                        $.each(ajax_output, function (i, v) {
                            tmp_data['sum'] += 1;
                            let tmp_k2 = v['normal' + tableNormalField.indexOf(tmp_k)];
                            // let numPattern = /^[-+]?\d+(.\d+)?$/;
                            // let datePattern = /^\d{4}-\d{2}-\d{2}/;
                            let nullPattern = /^\s*$/;
                            // 判断数值类型
                            if (field_type['str'].indexOf(tmp_k) > -1) {
                                if (nullPattern.test(tmp_k2) || tmp_k2 === undefined || !tmp_k2) {
                                    tmp_k2 = '无'
                                }
                            } else if (field_type['date'].indexOf(tmp_k) > -1) {
                                if (nullPattern.test(tmp_k2) || tmp_k2 === undefined || !tmp_k2) {
                                    tmp_k2 = '2000上半年'
                                } else {
                                    if (parseInt(tmp_k2.substring(5, 7)) < 7) {
                                        tmp_k2 = tmp_k2.substring(0, 4) + '上半年';
                                    } else {
                                        tmp_k2 = tmp_k2.substring(0, 4) + '下半年';
                                    }
                                }
                            } else {
                                if (nullPattern.test(tmp_k2) || tmp_k2 === undefined || !tmp_k2) {
                                    tmp_k2 = 0;
                                } else {
                                    tmp_k2 = parseInt(changeThreeDecimal_f(tmp_k2 / 10));
                                }
                            }
                            if (tmp_data['data'][tmp_k2] === undefined) {
                                tmp_data['data'][tmp_k2] = 1;
                                tmp_data_key.push(tmp_k2);
                            } else {
                                tmp_data['data'][tmp_k2] += 1
                            }
                        });
                        let pie_data_array = [];
                        tmp_data_key = tmp_data_key.sort();
                        $.each(tmp_data_key, function (i, v) {
                            let tmp_str = v.toString();
                            if (field_type['str'].indexOf(tmp_k) === -1 && field_type['date'].indexOf(tmp_k) === -1) {
                                tmp_str = String.format("{0}~{1}", 10 * v, 10 * (v + 1));
                            }
                            pie_data_array.push([tmp_str, parseFloat(changeThreeDecimal_f(tmp_data['data'][v] / tmp_data['sum'] * 100))]);
                        });
                        // console.log('pie_data_array: ' + pie_data_array);
                        let chart = {
                            plotBackgroundColor: null,
                            plotBorderWidth: null,
                            plotShadow: false
                        };
                        let title = {
                            text: this_model.find("option:selected").text() + ' - ' +
                                this_field.find("option:selected").text() +
                                ' 占比图 (总数: ' + tmp_data['sum'] + ')',
                            style: {
                                fontWeight: "bold"
                            }
                        };
                        let tooltip = {
                            pointFormat: '{series.name}: <b>{point.percentage:.1f}%</b>'
                        };
                        let plotOptions = {
                            pie: {
                                allowPointSelect: true,
                                cursor: 'pointer',
                                dataLabels: {
                                    enabled: false
                                },
                                showInLegend: true
                            }
                        };
                        let series = [{
                            type: 'pie',
                            name: '占比',
                            data: pie_data_array
                        }];
                        let credits = {
                            enabled: false,
                            text: ''
                        };
                        let json = {};
                        json.chart = chart;
                        json.title = title;
                        json.tooltip = tooltip;
                        json.series = series;
                        json.plotOptions = plotOptions;
                        json.credits = credits;
                        $('#plot_highcharts').highcharts(json);
                    } else if (plotClass.val() === 'scatter') {
                        // 获取数据
                        function collect_data(model_, field_) {
                            let res = {
                                'item_type': '',
                                'categories': [],
                                'data': []
                            };
                            if (model_ === 'None' || field_ === 'None') {
                                return res;
                            }
                            let item_type;
                            let tmp_k = model_ + '_' + field_;
                            let tmp_k2 = 'normal' + tableNormalField.indexOf(tmp_k);
                            //console.log(String.format("tmp_k: {0}; tmp_k2: {1}", tmp_k, tmp_k2));
                            let nullPattern = /^\s*$/;
                            // 判断数值类型
                            if (field_type['str'].indexOf(tmp_k) > -1) {
                                item_type = 'str';
                            } else if (field_type['date'].indexOf(tmp_k) > -1) {
                                item_type = 'date';
                            } else {
                                item_type = 'num';
                            }
                            // 根据数值类型读取结果
                            if (item_type === 'num') {
                                res['item_type'] = 'num';
                                $.each(ajax_output, function (i, v) {
                                    let v2 = v[tmp_k2];
                                    if (nullPattern.test(v2) || v2 === undefined || !v2) {
                                        v2 = 0
                                    }
                                    res['data'].push(v2);
                                });
                            } else if (item_type === 'date') {
                                res['item_type'] = 'date';
                                let tmp_list = [];
                                $.each(ajax_output, function (i, v) {
                                    let v2;
                                    if (nullPattern.test(v[tmp_k2]) || v[tmp_k2] === undefined || !v[tmp_k2]) {
                                        v2 = '2000上半年';
                                    } else {
                                        if (parseInt(v[tmp_k2].substring(5, 7)) < 7) {
                                            v2 = v[tmp_k2].substring(0, 4) + '上半年';
                                        } else {
                                            v2 = v[tmp_k2].substring(0, 4) + '下半年';
                                        }
                                    }
                                    tmp_list.push(v2);
                                });
                                let tmp_list_set = JSON.parse(JSON.stringify(tmp_list));
                                tmp_list_set = jQuery.unique(tmp_list_set.sort());
                                res['categories'] = tmp_list_set;
                                $.each(tmp_list, function (i, v) {
                                    res['data'].push(tmp_list_set.indexOf(v));
                                });
                            } else {
                                res['item_type'] = 'str';
                                let tmp_list = [];
                                $.each(ajax_output, function (i, v) {
                                    let v2 = v[tmp_k2];
                                    if (nullPattern.test(v2) || v2 === undefined || !v2) {
                                        v2 = '无'
                                    }
                                    tmp_list.push(v2);
                                });
                                //console.log(String.format("before tmp_list: {0}", tmp_list));
                                let tmp_list_set = JSON.parse(JSON.stringify(tmp_list));
                                tmp_list_set = jQuery.unique(tmp_list_set.sort());
                                res['categories'] = tmp_list_set;
                                $.each(tmp_list, function (i, v) {
                                    res['data'].push(tmp_list_set.indexOf(v));
                                });
                                //console.log(String.format("after tmp_list: {0}", tmp_list));
                            }
                            return res;
                        }

                        let this_models = [$('#plot_highcharts_model1'), $('#plot_highcharts_model2'),
                            $('#plot_highcharts_model3')];
                        let this_fields = [$('#plot_highcharts_model1').next().next(),
                            $('#plot_highcharts_model2').next().next(),
                            $('#plot_highcharts_model3').next().next(),
                        ];
                        if (this_models[0].val === 'None' || this_models[1].val === 'None'
                            || this_fields[0].val === 'None' || this_fields[1].val === 'None') {
                            $("#plotShowError").text("请正确选择x和y轴数据源(包括子表和字段)");
                            return;
                        }
                        let this_data = [];
                        for (let i = 0; i <= 2; i++) {
                            this_data.push(collect_data(this_models[i].val(), this_fields[i].val()))
                        }
                        console.log('before this_data:');
                        console.log(this_data);
                        if ($('#scatter_remove_abnormal').prop('checked') === true) {
                            function compute_limit(data_) {
                                let quart_75 = Quartile_75(data_);
                                let quart_25 = Quartile_25(data_);
                                return {
                                    "min_v": quart_25 - 1.5 * (quart_75 - quart_25),
                                    "max_v": quart_75 + 1.5 * (quart_75 - quart_25)
                                }
                            }

                            let tmp_data = [
                                {
                                    'item_type': this_data[0]['item_type'],
                                    'categories': this_data[0]['categories'],
                                    'data': []
                                },
                                {
                                    'item_type': this_data[1]['item_type'],
                                    'categories': this_data[1]['categories'],
                                    'data': []
                                },
                                {
                                    'item_type': this_data[2]['item_type'],
                                    'categories': this_data[2]['categories'],
                                    'data': []
                                }
                            ];
                            let x_bool = Array(this_data[0]['data'].length).fill('true');
                            let y_bool = Array(this_data[1]['data'].length).fill('true');
                            if (this_data[0]['item_type'] === 'num') {
                                // do something for x_bool
                                let limit = compute_limit(this_data[0]['data']);
                                // console.info('>>> min_v: ', limit.min_v , '; max_v: ', limit.max_v);
                                $.each(this_data[0]['data'], function (i, v) {
                                    if (v < limit.min_v || v > limit.max_v) {
                                        x_bool[i] = 'false'
                                    }
                                })
                            }
                            if (this_data[1]['item_type'] === 'num') {
                                // do something for y_bool
                                let limit = compute_limit(this_data[1]['data']);
                                // console.info('>>> y_bool >>> min_v: ', limit.min_v , '; max_v: ', limit.max_v);
                                $.each(this_data[1]['data'], function (i, v) {
                                    if (v < limit.min_v || v > limit.max_v) {
                                        y_bool[i] = 'false'
                                    }
                                })
                            }
                            // console.info("x_bool: ", x_bool, "; y_bool: ", y_bool);
                            $.each(x_bool, function (i, v) {
                                if (v === 'true' && y_bool[i] === 'true') {
                                    tmp_data[0]['data'].push(this_data[0]['data'][i]);
                                    tmp_data[1]['data'].push(this_data[1]['data'][i]);
                                    if (this_data[2]['item_type'] !== '') {
                                        tmp_data[2]['data'].push(this_data[2]['data'][i]);
                                    }
                                }
                            });
                            // console.info("tmp_data: ", tmp_data);
                            this_data = tmp_data;
                        }
                        console.log('after this_data:');
                        console.log(this_data);
                        if (this_data[2]['item_type'] === 'num') { // this_data[2]代表分组，需要把连续数字转换成分组
                            let tmp_list = [];
                            $.each(this_data[2]['data'], function (i, v) {
                                tmp_list.push(parseInt(v / 10));
                            });
                            let tmp_list_set = unique(tmp_list).sort();
                            console.info("tmp_list_set: ", tmp_list_set);
                            this_data[2]['categories'] = [];
                            $.each(tmp_list_set, function (i, v) {
                                this_data[2]['categories'].push(String.format("{0}~{1}", 10 * v, 10 * (v + 1)));
                            });
                            this_data[2]['data'] = [];
                            $.each(tmp_list, function (i, v) {
                                this_data[2]['data'].push(tmp_list_set.indexOf(v));
                            });
                            this_data[2]['item_type'] = 'str';
                        } else if (this_data[2]['item_type'] === 'date') {
                            this_data[2]['item_type'] = 'str';
                        }
                        console.log('after2 this_data:');
                        console.log(this_data);
                        let chart = {
                            type: 'bubble',
                            zoomType: 'xy'
                        };
                        let title = {
                            text: this_models[0].val() + ' - ' + this_fields[0].val() + ' .VS. ' +
                                this_models[1].val() + ' - ' + this_fields[1].val()
                        };
                        let tooltip = {};
                        let plotOptions = {};
                        let series = [];
                        let credits = {
                            enabled: false,
                            text: ''
                        };
                        let xAxis = {
                            title: {
                                enabled: true,
                                text: this_models[0].val() + ' - ' + this_fields[0].val()
                            },
                            startOnTick: true,
                            endOnTick: true,
                            showLastLabel: true
                        };
                        let yAxis = {
                            title: {
                                text: this_models[1].val() + ' - ' + this_fields[1].val()
                            }
                        };
                        let json = {};
                        if (this_data[0]['item_type'] === 'num' && this_data[1]['item_type'] === 'num') {
                            // 画正常散点图
                            chart.type = 'scatter';
                            plotOptions = {
                                scatter: {
                                    allowPointSelect: true,
                                    cursor: 'pointer',
                                    dataLabels: {
                                        enabled: false
                                    },
                                    showInLegend: false,
                                    marker: {
                                        radius: 5,
                                        states: {
                                            hover: {
                                                enabled: true
                                            }
                                        }
                                    },
                                    states: {
                                        hover: {
                                            marker: {
                                                enabled: false
                                            }
                                        }
                                    }
                                }
                            };
                            if (this_data[2]['item_type'] === 'str') { // 有分组
                                title.text += ' (group by ' + this_models[2].val() + ' - ' + this_fields[2].val() + ') ';
                                plotOptions.scatter.showInLegend = true;
                                json.legend = {
                                    layout: 'vertical',
                                    align: 'left',
                                    verticalAlign: 'top',
                                    x: 100,
                                    y: 70,
                                    floating: true,
                                    backgroundColor: (Highcharts.theme && Highcharts.theme.legendBackgroundColor) || '#FFFFFF',
                                    borderWidth: 1
                                };
                                let name_series = [];
                                let data_series = [];
                                $.each(this_data[2]['categories'], function (i, v) {
                                    name_series.push(v);
                                    data_series.push([]);
                                });
                                $.each(this_data[2]['data'], function (i, v) {
                                    data_series[v].push([this_data[0]['data'][i], this_data[1]['data'][i]]);
                                });
                                $.each(data_series, function (i, v) {
                                    series.push({
                                        name: name_series[i],
                                        data: v
                                    });
                                });
                            } else { // 无分组
                                let data_series = [];
                                $.each(this_data[0]['data'], function (i, v) {
                                    // console.log(String.format("无分组 {0} {1}", v, this_data[1]['data'][i]));
                                    data_series.push([v, this_data[1]['data'][i]]);
                                });
                                series.push({
                                    name: 'None',
                                    data: data_series
                                });
                            }
                        } else if (this_data[0]['item_type'] === 'num' && this_data[1]['item_type'] !== 'num') {
                            // 画气泡图(x是数值, y是字符串/日期)
                            series = plot_bubble_by_group(this_data, this_models, this_fields, 1, 0,
                                xAxis, yAxis, plotOptions, tooltip, title);
                        } else if (this_data[0]['item_type'] !== 'num' && this_data[1]['item_type'] === 'num') {
                            // 画气泡图(x是字符串/日期, y是数值)
                            series = plot_bubble_by_group(this_data, this_models, this_fields, 0, 1,
                                xAxis, yAxis, plotOptions, tooltip, title);
                        } else {
                            // 画气泡图(x是字符串/日期, y是字符串/日期)
                            series = plot_bubble_by_group(this_data, this_models, this_fields, 0, 0,
                                xAxis, yAxis, plotOptions, tooltip, title);
                        }
                        // console.log("series:");
                        // console.log(series);
                        json.chart = chart;
                        json.title = title;
                        json.tooltip = tooltip;
                        json.series = series;
                        json.plotOptions = plotOptions;
                        json.credits = credits;
                        json.xAxis = xAxis;
                        json.yAxis = yAxis;
                        $('#plot_highcharts').highcharts(json);
                    }
                });
            });


        })

    </script>
{% endblock %}